﻿#include "flowchart.h"
#include "ui_flowchart.h"
#include <QDebug>
#include <algorithm>

FlowChart::FlowChart(OpcUA_QThread * opcUA, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FlowChart)
{
    ui->setupUi(this);
    //设置表头
    InitTableHeader();
    setColumnsNonEdit();

    //初始化数据处理对象，绑定信号槽
    m_flowData = new FlowData(opcUA, this);
    connect(m_flowData, &FlowData::paramRangeError, this, &FlowChart::onParamRangeError);
    connect(m_flowData, &FlowData::writeSuccess, this, &FlowChart::onWriteSuccess);

    //初始化流程定时器（100ms精度）
    m_flowTimer = new QTimer(this);
    m_flowTimer->setInterval(100);
    m_flowTimer->setSingleShot(false);
    connect(m_flowTimer, &QTimer::timeout, this, &FlowChart::onTimerTimeout);

    //绑定表格修改事件
    connect(ui->tableWidget, &QTableWidget::itemChanged, this, &FlowChart::onTableItemChanged);

    //设置背景色
    m_originalRowBgColor =  QColor(255, 255, 255);

    //初始化总时间显示
    ui->lineEdit_totalTime->setReadOnly(true);
    ui->lineEdit_totalTime->setText(u8"当前时间：0.0 秒");
}

FlowChart::~FlowChart()
{
    m_flowTimer->stop();
    delete m_flowTimer;
    delete m_flowData;
    delete ui;
}

void FlowChart::on_receiveTemperature(int16_t temperature1, int16_t temperature2)
{
    m_flowData->setTemperature(temperature1, temperature2);
}

void FlowChart::InitTableHeader()
{
    const int totalColumns = 26;  //总列数
    const int dataRows = 0;      //默认数据行数
    ui->tableWidget->setColumnCount(totalColumns);
    ui->tableWidget->setRowCount(dataRows + HEADER_ROW_COUNT);  //数据行+伪表头行

    //表头配置（行合并+列合并）
    QVector<QPair<QString, int>> rowMergeHeaders = {
        {"step", 0}, {"Duration Time(s)", 1}, {"Total Time(s)", 2},
        {"Set Temprature 1", 3}, {"Set Temprature 2", 4}, {"Set Pressure", 5}
    };
    // 列合并表头调整：O-3改为N2，调整起始列索引
    QVector<QPair<QString, int>> colMergeHeaders = {
        {"Mo1", 6}, {"Mo2", 11}, {"O-1", 16}, {"O-2", 20}, {"N2", 24}
    };

    //表头样式
    QFont headerFont;
    headerFont.setBold(true);
    QColor headerBgColor(120, 180, 255);    //主表头背景色（浅蓝色）
    QColor subHeaderBgColor(120, 255, 255); //子表头背景色（浅青色）

    //处理行合并表头（跨2行）
    for (const auto& header : rowMergeHeaders)
    {
        int col = header.second;
        ui->tableWidget->setSpan(0, col, 2, 1);

        QTableWidgetItem* item = new QTableWidgetItem(header.first);
        item->setFlags(item->flags() & ~Qt::ItemIsEditable);
        item->setTextAlignment(Qt::AlignCenter);
        item->setBackground(headerBgColor);
        item->setFont(headerFont);
        ui->tableWidget->setItem(0, col, item);
    }

    //处理列合并表头（跨5列）
    for (const auto& header : colMergeHeaders)
    {
        int col = header.second;
        // 设置跨列数：Mo1、Mo2保持5列，O-1、O-2改为4列，N2改为2列
        int colSpan = (header.first == "Mo1" || header.first == "Mo2") ? 5 :
                      (header.first == "O-1" || header.first == "O-2") ? 4 : 2;
        ui->tableWidget->setSpan(0, col, 1, colSpan);

        QTableWidgetItem* item = new QTableWidgetItem(header.first);
        item->setFlags(item->flags() & ~Qt::ItemIsEditable);
        item->setTextAlignment(Qt::AlignCenter);
        item->setBackground(headerBgColor);
        item->setFont(headerFont);
        ui->tableWidget->setItem(0, col, item);
    }

    //处理子表头（Source、Push、Line、Run、Press）
    for (const auto& header : colMergeHeaders)
    {
        int startCol = header.second;
        QStringList subHeaders;

        // 根据不同主表头设置不同子表头
        if (header.first == "Mo1" || header.first == "Mo2")
        {
            subHeaders << "Source" << "Push" << "Line" << "Run" << "Press";
        }
        else if (header.first == "O-1" || header.first == "O-2")
        {
            subHeaders << "Source" << "Push" << "Line" << "Run";
        }
        else if (header.first == "N2")
        {
            subHeaders << "Source" << "Valve";
        }


        for (int i = 0; i < subHeaders.size(); ++i)
        {
            int col = startCol + i;
            QTableWidgetItem* item = new QTableWidgetItem(subHeaders[i]);
            item->setFlags(item->flags() & ~Qt::ItemIsEditable);
            item->setTextAlignment(Qt::AlignCenter);
            item->setBackground(subHeaderBgColor);
            item->setFont(headerFont);
            ui->tableWidget->setItem(1, col, item);
        }
    }

    //表格基础样式配置
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableWidget->horizontalHeader()->setDefaultSectionSize(60);
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(40);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    ui->tableWidget->setEditTriggers(
        QTableWidget::DoubleClicked | QTableWidget::SelectedClicked | QTableWidget::EditKeyPressed
    );
}

void FlowChart::exportToExcel()
{
    QString filter = "CSV Files (*.csv)";
    QString filePath = QFileDialog::getSaveFileName(
        nullptr,
        "保存CSV文件",
        QDir::homePath(),
        "CSV Files (*.csv)");
    //自动补充.csv后缀（如果用户未输入）
    if (!filePath.isEmpty() && !filePath.endsWith(".csv", Qt::CaseInsensitive)) {
        filePath += ".csv";
    }

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        QMessageBox::critical(this, tr(u8"错误"), tr(u8"无法打开文件：%1").arg(file.errorString()));
        return;
    }

    QTextStream out(&file);

    //遍历表格所有行（包括伪表头行）
    for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
    {
        QStringList rowData;
        for (int col = 0; col < ui->tableWidget->columnCount(); ++col)
        {
            //处理合并单元格，只保留左上角内容
            if ((ui->tableWidget->rowSpan(row, col) > 1 || ui->tableWidget->columnSpan(row, col) > 1) &&
                ui->tableWidget->item(row, col))
            {
                rowData << escapeCsv(ui->tableWidget->item(row, col)->text());
            }
            else if (ui->tableWidget->item(row, col))
            {
                rowData << escapeCsv(ui->tableWidget->item(row, col)->text());
            }
            else
            {
                rowData << "";
            }
        }
        out << rowData.join(",") << "\n";
    }

    file.close();
    QMessageBox::information(this, tr(u8"成功"), tr(u8"表格已导出为CSV文件：\n%1").arg(filePath));
}

void FlowChart::onTableItemChanged(QTableWidgetItem *changedItem)
{
    if (!changedItem) return;

    int row = changedItem->row();
    int col = changedItem->column();
    QString text = changedItem->text();

    //跳过伪表头行
    if (row < HEADER_ROW_COUNT) return;

    //qDebug() << QString(u8"FlowChart:单元格(%1, %2)被修改为: %3").arg(row).arg(col).arg(text);

    //校验输入合法性
    bool valid = m_flowData->validateTableData(col, text);
    if (!valid)
    {
        ui->tableWidget->blockSignals(true);
        changedItem->setText(u8"");
        ui->tableWidget->blockSignals(false);
        return;
    }

    //处理Duration Time修改后的时间更新
    if (col == 1)
    {
        m_flowData->updateTotalTime(ui->tableWidget, HEADER_ROW_COUNT);
    }

    //更新参数列表
    m_flowData->updateParamFromTable(ui->tableWidget, row, HEADER_ROW_COUNT);
}

void FlowChart::keyPressEvent(QKeyEvent *event)
{
    if (ui->tableWidget->hasFocus() && event->key() == Qt::Key_Delete)
    {
        on_pushButton_deleteRow_clicked();
        event->accept();
    }
    else
    {
        QWidget::keyPressEvent(event);
    }
}

void FlowChart::on_pushButton_deleteRow_clicked()
{
    QList<QTableWidgetItem*> selectedItems = ui->tableWidget->selectedItems();
    if (selectedItems.isEmpty())
    {
        QMessageBox::information(this, u8"提示", u8"请先选择要删除的行");
        return;
    }

    //收集需要删除的行（跳过伪表头）
    QSet<int> targetRows;
    for (auto item : selectedItems)
    {
        int row = item->row();
        if (row >= HEADER_ROW_COUNT)
            targetRows.insert(row);
    }

    if (targetRows.isEmpty())
    {
        QMessageBox::information(this, u8"提示", u8"无法删除伪表头行");
        return;
    }

    //逆序删除避免索引错乱
    QList<int> rows(targetRows.begin(), targetRows.end());
    std::sort(rows.begin(), rows.end(), std::greater<int>());
    for (int row : rows)
        ui->tableWidget->removeRow(row);

    //重新计算Total Time
    m_flowData->updateTotalTime(ui->tableWidget, HEADER_ROW_COUNT);

    //重置背景色
    if (!m_flowTimer->isActive())
        resetAllRowBgColor();

    //重新计算step步骤号
    updateStepNumbers();

    QMessageBox::information(this, u8"删除成功",
                           QString(u8"共删除%1行数据，已重新计算Total Time！").arg(targetRows.size()));
}

void FlowChart::on_pushButton_insertRowAbove_clicked()
{
    //获取插入位置
    QList<QTableWidgetItem*> selectedItems = ui->tableWidget->selectedItems();
    int insertRow = selectedItems.isEmpty() ? ui->tableWidget->rowCount() : selectedItems.first()->row();

    //限制插入位置
    if (insertRow < HEADER_ROW_COUNT)
    {
        QMessageBox::warning(this, u8"插入失败", u8"无法在伪表头上方插入行！");
        return;
    }

    //插入新行并初始化
    ui->tableWidget->insertRow(insertRow);
    for (int col = 0; col < ui->tableWidget->columnCount(); ++col)
    {
        QTableWidgetItem* newItem = new QTableWidgetItem();
        Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
        if (col != 2)  //Total Time列不可编辑
            flags |= Qt::ItemIsEditable;
        newItem->setFlags(flags);
        newItem->setBackground(m_originalRowBgColor);
        newItem->setTextAlignment(Qt::AlignCenter);
        ui->tableWidget->setItem(insertRow, col, newItem);
    }

    //选中新插入的行
    ui->tableWidget->selectRow(insertRow);

    //重新计算Total Time
    m_flowData->updateTotalTime(ui->tableWidget, HEADER_ROW_COUNT);

    //重新计算step步骤号
    updateStepNumbers();

    QMessageBox::information(this, u8"插入成功",
                           QString(u8"已在第%1行上方插入新行").arg(insertRow + 1));
}

void FlowChart::on_pushButton_exportToExcel_clicked()
{
    exportToExcel();
}

QString FlowChart::escapeCsv(const QString &text)
{
    //判断是否包含特殊符号，单独处理。
    if (text.contains(',') || text.contains('"') || text.contains('\n') || text.contains('\r'))
    {
        QString escaped = text;
        escaped.replace('"', "\"\"");
        return "\"" + escaped + "\"";
    }
    return text;
}

//设置某列不可编辑
void FlowChart::setColumnsNonEdit()
{
    const int nonEditableColumn = 2;  //Total Time列
    if (nonEditableColumn < 0 || nonEditableColumn >= ui->tableWidget->columnCount())
        return;

    for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
    {
        QTableWidgetItem* item = ui->tableWidget->item(row, nonEditableColumn);
        if (!item)
        {
            item = new QTableWidgetItem();
            ui->tableWidget->setItem(row, nonEditableColumn, item);
        }
        item->setFlags(item->flags() & ~Qt::ItemIsEditable);
    }
}

void FlowChart::on_pushButton_start_clicked()
{
    QVector<FlowParam> params = m_flowData->getParams();
    if (params.isEmpty())
    {
        QMessageBox::warning(this, u8"未保存数据", u8"请先点击【保存设置】按钮，确认有效步骤数据！");
        return;
    }

    //初始化步骤和定时器
    m_currentStepIndex = 0;
    m_timerStartTime = QDateTime::currentMSecsSinceEpoch();
    m_flowTimer->stop();

    //执行第一步
    m_flowData->writeStepToKepserver(params[0]);
    m_flowData->setActiveStatus(true);
    setCurrentStepRowBgColor(m_currentStepIndex);

    //启动定时器
    m_flowTimer->start();
    QMessageBox::information(this, u8"流程启动",
                           QString(u8"已启动流程，共%1步，将按Total Time自动执行！").arg(params.size()));

    //开始运行了，需要触发信号，目前信号在MainWindow绑定给HomePage界面
    emit signals_flowChartStart();
    //触发信号，把数据传递给首页界面更新期望值
    sendDesiredValue(params, 0);
}

void FlowChart::on_pushButton_saveSetting_clicked()
{
    //校验表头下方第一行（数据区第一行）是否存在
     const int firstDataRow = HEADER_ROW_COUNT; // 表头下方第一行索引
     if (firstDataRow >= ui->tableWidget->rowCount())
     {
         QMessageBox::warning(this, u8"保存失败", u8"至少需要一行数据！");
         return;
     }

     //校验表头下方第一行所有可编辑单元格是否为空
     for (int col = 0; col < ui->tableWidget->columnCount(); ++col)
     {
         // 跳过不可编辑的Total Time列（索引2）
         if (col == 2)
             continue;

         QTableWidgetItem* item = ui->tableWidget->item(firstDataRow, col);
         if (!item || item->text().isEmpty())
         {
             QMessageBox::warning(this, u8"保存失败",
                                QString(u8"表头下方第一行的第%1列不能为空，请填写完整！").arg(col + 1));
             return;
         }
     }

    int validCount = m_flowData->saveParamsFromTable(ui->tableWidget, HEADER_ROW_COUNT);

    if (validCount == 0)
        QMessageBox::information(this, u8"提示", u8"无有效数据行（Step列不能为空）");
    else
        QMessageBox::information(this, u8"保存成功", QString(u8"共保存%1条有效步骤").arg(validCount));
}

void FlowChart::onTimerTimeout()
{
    QVector<FlowParam> params = m_flowData->getParams();
    if (params.isEmpty())
    {
        m_flowTimer->stop();
        return;
    }

    //更新当前运行时间
    qint64 currentTimeMs = QDateTime::currentMSecsSinceEpoch();
    double elapsedSec = (currentTimeMs - m_timerStartTime) / 1000.0;
    ui->lineEdit_totalTime->setText(QString(u8"当前时间：%1 秒").arg(elapsedSec, 0, 'f', 1));

    //检查是否完成所有步骤
    if (m_currentStepIndex >= params.size())
    {
        m_flowTimer->stop();
        ui->lineEdit_totalTime->setText(u8"当前时间：0.0 秒");
        resetAllRowBgColor();
        QMessageBox::information(this, u8"流程完成", u8"所有步骤执行完毕");
        m_currentStepIndex = 0;
        m_timerStartTime = 0;

        //这里已经运行结束，需要发信号，目前信号传递给HomePage界面。
        m_flowData->setActiveStatus(false);
        emit signals_flowChartStop();

        return;
    }

    //判断是否需要切换步骤
    if (m_flowData->shouldSwitchStep(params, m_currentStepIndex, elapsedSec))
    {
        m_currentStepIndex++;
        if (m_currentStepIndex < params.size())
        {
            qDebug() << u8"FlowChart::onTimerTimeout() 写入了一次";
            m_flowData->writeStepToKepserver(params[m_currentStepIndex]);
            setCurrentStepRowBgColor(m_currentStepIndex);

            //触发信号，把数据传递给首页界面更新期望值
            sendDesiredValue(params, m_currentStepIndex);
        }
    }
}

void FlowChart::onParamRangeError(const QString& errMsg)
{
    QMessageBox::warning(this, u8"输入错误", errMsg);
    qDebug() << u8"FlowChart:有错误反馈了，还需要处理····" << errMsg;
}

void FlowChart::onWriteSuccess(const QString& msg)
{
    emit logOutput(u8"FlowData写入反馈：" + msg);
    qDebug() << u8"FlowChart:有写入反馈了，还需要处理····" << msg;
}

void FlowChart::on_pushButton_stop_clicked()
{
    m_flowTimer->stop();
    m_timerStartTime = 0;
    m_currentStepIndex = 0;
    ui->lineEdit_totalTime->setText(u8"当前时间：0.0 秒");
    resetAllRowBgColor();
    m_flowData->stopWrite();
    m_flowData->setActiveStatus(false);
    QMessageBox::information(this, u8"流程停止", u8"流程已手动停止！");
}

//重置背景色
void FlowChart::resetAllRowBgColor()
{
    QVector<FlowParam> params = m_flowData->getParams();
    for (int i = 0; i < params.size(); ++i)
    {
        int tableRow = HEADER_ROW_COUNT + i;
        if (tableRow >= ui->tableWidget->rowCount())
            continue;

        for (int col = 0; col < ui->tableWidget->columnCount(); ++col)
        {
            QTableWidgetItem* item = ui->tableWidget->item(tableRow, col);
            if (item)
                item->setBackground(m_originalRowBgColor);
        }
    }
}

//设置正在执行的步骤的背景色
void FlowChart::setCurrentStepRowBgColor(int stepIndex)
{
    QVector<FlowParam> params = m_flowData->getParams();
    if (stepIndex < 0 || stepIndex >= params.size())
        return;

    int tableRow = HEADER_ROW_COUNT + stepIndex;
    if (tableRow >= ui->tableWidget->rowCount())
        return;

    resetAllRowBgColor();
    QColor blueBg(173, 216, 230);
    for (int col = 0; col < ui->tableWidget->columnCount(); ++col)
    {
        QTableWidgetItem* item = ui->tableWidget->item(tableRow, col);
        if (item)
            item->setBackground(blueBg);
    }
}

//更新Step列的步骤号
void FlowChart::updateStepNumbers()
{
    //从伪表头行之后开始更新
    for (int row = HEADER_ROW_COUNT; row < ui->tableWidget->rowCount(); ++row)
    {
        int stepNumber = row - HEADER_ROW_COUNT + 1;  //计算当前行的step编号
        QTableWidgetItem* item = ui->tableWidget->item(row, 0);

        if (!item)
        {
            item = new QTableWidgetItem(QString::number(stepNumber));
            ui->tableWidget->setItem(row, 0, item);
        }
        else
        {
            item->setText(QString::number(stepNumber));
        }

        //设置为不可编辑
        item->setFlags(item->flags() & ~Qt::ItemIsEditable);
    }
}

void FlowChart::sendDesiredValue(QVector<FlowParam> params, int currentStepIndex)
{
    QVector<int16_t> myflowmeter;
    QVector<int16_t> mypressuremeter;
    myflowmeter.append(params[currentStepIndex].N2Source);
    myflowmeter.append(params[currentStepIndex].o2Push);
    myflowmeter.append(params[currentStepIndex].o2Source);
    myflowmeter.append(params[currentStepIndex].o1Push);
    myflowmeter.append(params[currentStepIndex].o1Source);
    myflowmeter.append(params[currentStepIndex].mo1Push);
    myflowmeter.append(params[currentStepIndex].mo1Source);
    myflowmeter.append(params[currentStepIndex].mo2Source);
    myflowmeter.append(params[currentStepIndex].mo2Push);

    mypressuremeter.append(params[currentStepIndex].mo1Press);
    mypressuremeter.append(params[currentStepIndex].mo2Press);

    emit signals_sendDesiredValue(myflowmeter, mypressuremeter);
}
